//
// OpenTemplate Compiler
// Copyright (c) 2006
// by OpenArrow Software ( http://www.openarrow.com )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using System.IO;

namespace OpenArrow.Utils
{
    /// <summary>
    /// Parses command line arguments
    /// </summary>
    /// <internal />
    internal class CommandLineParser
    {
        #region Private Fields

        private List<string> unnamedArguments = new List<string>();
        private NameValueCollection namedArguments = new NameValueCollection();
        private List<string> switches = new List<string>();

        #endregion

        #region Public Properties

        public List<string> UnnamedArguments
        {
            get { return unnamedArguments; }
        }

        public NameValueCollection NamedArguments
        {
            get { return namedArguments; }
        }

        public List<string> Switches
        {
            get { return switches; }
        }

        #endregion

        #region Constructors and Methods

        public CommandLineParser(string[] args)
        {
            bool readUnnamed = false;
            string currentName = String.Empty;
            string currentValue = String.Empty;
            foreach (string arg in args)
            {
                if (!readUnnamed && arg.StartsWith("-"))
                    readUnnamed = true;

                if (!readUnnamed)
                {
                    if (arg.StartsWith("@"))
                        LoadResponseFile(arg.Substring(1));
                    else
                        unnamedArguments.Add(arg);
                }
                else
                {
                    if (arg.StartsWith("-"))
                    {
                        if (!String.IsNullOrEmpty(currentName))
                        {
                            AddNamedArgument(currentName, currentValue);
                            currentName = String.Empty;
                            currentValue = String.Empty;
                        }
                        currentName = arg.Substring(1);
                    }
                    else
                    {

                        if (!String.IsNullOrEmpty(currentValue))
                            currentValue = String.Format("{0};{1}", currentValue, arg);
                        else
                            currentValue = arg;
                    }
                }
            }
            AddNamedArgument(currentName, currentValue);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.IO.IOException.#ctor(System.String,System.Exception)")]
        private void LoadResponseFile(string responseFile)
        {
            if (!File.Exists(responseFile))
            {
                try
                {
                    StreamReader reader = new StreamReader(responseFile);
                    string line = null;
                    while ((line = reader.ReadLine()) != null)
                    {
                        ParseArgument(line);
                    }
                }
                catch (IOException ex)
                {
                    throw new IOException("Unable to read response file", ex);
                }
            }
        }

        private void ParseArgument(string line)
        {
            if (line.StartsWith("-"))
                ParseNamedArgument(line);
            else
                unnamedArguments.Add(line);
        }

        private void ParseNamedArgument(string line)
        {
            string[] arg = line.Split();
            NamedArguments.Add(arg[0], String.Join(" ", arg, 1, arg.Length - 1));
        }

        private void AddNamedArgument(string currentName, string currentValue)
        {
            if (String.IsNullOrEmpty(currentValue))
                switches.Add(currentName);
            else
                namedArguments.Add(currentName, currentValue);
        } 

        #endregion
    }
}
